import {createRouter, createWebHistory, type RouteRecordRaw} from 'vue-router'
import Layout from "@/layout/index.vue";
import NProgress from "nprogress";
import {PageEnum} from "@/config/enums/pageEnum";
import useUserStore from "@/base/stores/modules/user";
import {isExternal} from "@/utils/validate";
import RouterManager from "@/manager/base/RouterManager";

/**
 * 固定路由
 */
export const constantRoutes: Array<RouteRecordRaw> = [
    {
        path: '/:pathMatch(.*)*',
        component: () => import('@/views/system/error/404.vue')
    },
    {
        path: '/403',
        component: () => import('@/views/system/error/403.vue')
    },
    {
        path: '/login',
        component: () => import('@/views/system/account/login.vue')
    },

]


/**
 * 基类
 */
export const INDEX_ROUTE_NAME = Symbol()
export const indexRoute: RouteRecordRaw = {
    path: '/',
    component: Layout,
    name: INDEX_ROUTE_NAME,
}


/**
 * 创建router
 */
const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes: constantRoutes,
})


// -------------------------------- 过程  --------------------------------------------------------

/**
 * 定义配置
 *  是否显示转轮
 */
NProgress.configure({showSpinner: false})

const loginPath = PageEnum.LOGIN
const defaultPath = PageEnum.INDEX

// 免登录白名单
const whiteList: string[] = [PageEnum.LOGIN, PageEnum.ERROR_403]


/**
 * 路由前置拦截器
 */
router.beforeEach(async (to, from, next) => {
        NProgress.start()
        const userStore = useUserStore()


        // 存在token
        if (userStore.token) {
            // 判断是否存有用户信息
            const hasGetUserInfo = Object.keys(userStore.userInfo).length !== 0

            if (hasGetUserInfo) {
                // 如果是登陆放行到index 无需重新登陆
                if (to.path === loginPath) {
                    next({path: defaultPath})
                }

                // 其他页面放行
                else {
                    next()
                }
            } else {

                try {
                    // 获取用户信息
                    await userStore.getSystemAdminInfo()
                    // 获取枚举
                    await userStore.getSystemMenuRoute()


                    const routes: RouteRecordRaw[] = userStore.routes

                    // 找到第一个有效路由 进行重定向
                    // @ts-ignore
                    indexRoute.redirect = {name: RouterManager.findFirstValidRoute(routes)}
                    // 添加index  /路由
                    router.addRoute(indexRoute)


                    routes.forEach((route: any) => {
                        // https 则不插入
                        if (isExternal(route.path)) {
                            return
                        }

                        if (!route.children) {
                            router.addRoute(INDEX_ROUTE_NAME, route)
                            return
                        }

                        // 动态添加可访问路由表
                        router.addRoute(route)
                    })


                    // 放行  replace 后缀删除
                    next({...to, replace: true})
                } catch (err) {
                    // 移除token
                    await userStore.resetLoginInfo()
                    // 到登陆页面
                    next({path: loginPath, query: {redirect: to.fullPath}})
                }
            }
        }



        // 登陆放行
        else if (whiteList.includes(to.path)) {
            // 在免登录白名单，直接进入
            next()
        }

        // 其他请求无token 进登陆重定向到路由path
        else {
            next({path: loginPath, query: {redirect: to.fullPath}})
        }
    }
)


/**
 * 路由后置处理器
 */
router.afterEach(() => {
    NProgress.done()
})


export default router
